## @file RPCMethods.py
#
# All the functions accessible as WebServices through /ws/xxx where xx is the function name
# 
# Arguments are passed through POST and must be named (ie a=1&b=1)
# A SID to maintain the Statefull status is passed (the string changes for each calls, sor the callse muste be serialized.
# 
#  \msc
#  JS,Py;
#  JS->Py [label="Function Call", URL="/ws/func"];
#  Py->JS [label="Response", URL=""];
#  Py->JS [label="Error", URL=""];
#  \endmsc
#  
 
# Created on Jul 17, 2009
# @author: ca3jmaupas
# 

import datetime, logging
from google.appengine.ext import db
from django.utils import simplejson as json
from model.Model import *

## Convenience Function to delete all objects from a table in Google app DB
#
def delete_all_objects(obj_class,       #! Class = table = base Entity 
                       num_del = 300):  #! Number of deletes per loop
#                delete_all_objects (Model.QuizItem) +\
    s="<br/>"+obj_class.__class__.__name__+":"
    while True:
        #try:
            objs = obj_class.all().fetch(num_del)
            num_objs = len(objs)
            if num_objs == 0:
                return
            s+= " deleted %d" % num_objs 
            db.delete(objs)
        #except :
        #    print " error - continuing ..." 
            
## Defines the methods that can be RPCed.
#
# All the functions accessible as WebServices through /ws/xxx where xx is the function name
# 
# Arguments are passed through POST and must be named (ie a=1&b=1)
# A SID to maintain the Statefull status is passed (the string changes for each calls, sor the callse muste be serialized.
# 
# NOTE: Do not allow remote callers access to private/protected "_*" methods.
#
# Created on Jul 17, 2009
# @author: ca3jmaupas
# 
class RPCMethods (object):
    """ Defines the methods that can be RPCed.
    
    """

    def delSessions (self, *args):
        #ints = [float(arg) for arg in args]
        from model.Session import Session
        deleted = []
        n=0
        for entity in Session.all().fetch(1000):
            n+=1
            deleted.append(entity)
        db.delete(deleted)
        return "Number of rows deleted %d " % n

  
    def Add(self, *args):
        """Add 2 Numbers
        Just an example
        """
        # The JSON encoding may have encoded integers as strings.
        # Be sure to convert args to any mandatory type(s).
        if len(args)>0:
            try:
                ints = [float(arg) for arg in args]
            except:
                return None
            return sum(ints)
        else:
            return None
    add=Add
    
    def Avg(self, *args):
        # The JSON encoding may have encoded integers as strings.
        # Be sure to convert args to any mandatory type(s).
        ints = [float(arg) for arg in args]
        return round(sum(ints) / len(ints),2)
    
    def getTime(self):
        now=datetime.datetime.now()
        return str(now)
    
    def start(self):
        return None

    def allUserPrefs(self, *args):
        """return all UP"""
        q = db.GqlQuery("SELECT * FROM UserPrefs ORDER by lastUpdate")
        if q.count() ==0 : return []
        else: return q.fetch(1000) # return (str(s) for s in q)

    def allSessions(self, user=None):
        """return all sessions"""
        if user == None:
            q = db.GqlQuery("SELECT * FROM Session ORDER BY lastUpdate")
        else:
            q = db.GqlQuery("SELECT * FROM Session WHERE user=:l","UID"+user.user_id())
        if q.count() ==0 : return []
        else: return q.fetch(1000) # return (str(s) for s in q)


    def getUsers(self, line1=None, line2=None):
        # TODO: between libe1 and line2
        q = db.GqlQuery("SELECT * FROM User ORDER BY user")
        if q.count() ==0 : return []
        return q.fetch(1000) # return (str(s) for s in q)
        
    def getUser(self, user):
        q = db.GqlQuery("SELECT * FROM User WHERE user=:l",user)
        if q.count() !=1 : return None
        return q.get()

    def setPlayer(self, *args):
#        ut=UserToken(token=genToken(),pin=genPin(),quizKey=bv)
        k1=str(id)
        logging.info( "Create User "+k1 )
        QB=Player.get_or_insert(k1)
        for k,v in args:
            QB.k=v
        QB.put()
        
    ## Create a Game Room
    # 
    # @param room Name : all details
    #
    def fCreateGameRoom (self, **args):
        k1=str(id)
        logging.info( "Create Room "+k1 )
        QB=GameRoom.get_or_insert(k1)
        # updateFCromArgs(args)
        for k, v in args: QB.k=v
        QB.put()

    ## List game servers
    # no argument TODO: filter
    def listServers (self, *args):
        logging.info( "listServers "+str(args) )
        return Server # "http://worldofmythology.appspot.com/"
 
Server={\
    "name":"Test",\
    "url":"http://worldofmythology.appspot.com/",\
    "ping":100,\
    "access":[1,2,3]}
    
if __name__ == '__main__':
    def f(*arg,**args):
        for k in args:
            print k,args[k]
        for k in arg:
            print k
    f(1,2,3)
    f(a=1,b=2,c=3)
    f(1,2,3,a=1,b=2,c=3)